package org.dromara.generator.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.generator.domain.*;
import org.dromara.generator.domain.bo.CustomBo;
import org.dromara.generator.mapper.CustomMapper;
import org.dromara.generator.service.IGenTableService2;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

import static org.dromara.generator.domain.SqlAgreeEnum.*;
import static org.dromara.generator.domain.SqlOperateEnum.*;

/**
 * 道路运输空气监测
 *
 * @author Lion Li
 * @date 2023-07-26
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/srv/consum")
public class CustomController extends BaseController {
    private final IGenTableService2 genTableService;

    private final CustomMapper customMapper;

    /**
     * 查询代码生成业务2sql列表
     */
    @SaCheckPermission("srv:consum:list")
    @PostMapping("/list")
    public TableDataInfo<List<Map<String, Object>>> list(
        @Validated @RequestBody CustomBo bo,
        PageQuery pageQuery) {
        GenTable2 table = genTableService.selectGenTableById(bo.getId());
        if (table == null) {
            throw new ServiceException("error table");
        }
        List<GenTableColumn2> rows = genTableService.selectGenTableColumnListByTableId(bo.getId());
        if (rows == null) {
            throw new ServiceException("error rows");
        }
        Map<String, GenTableColumn2> map = new HashMap<>(rows.size());

        rows.stream().forEach(obj -> {
            map.put(obj.getJavaField(), obj);
        });

        Collection<CustomWhereBody> searchs = bo.getSearchs();
        Collection<CustomAgreeBody> agrees = bo.getAgrees();

        Collection<CustomField> shows = bo.getShows();
        Collection<CustomField> groups = bo.getGroups();

        List<String> fieldList = new ArrayList<>();
        List<String> orderList = new ArrayList<>();
        List<String> groupList = new ArrayList<>();
        List<Map<String, Object>> searchList = new ArrayList<>();
        if (shows == null && agrees == null) {
            throw new ServiceException("error shows || agreess");
        }
        if (shows != null) {
            shows.forEach(obj -> {
                String columnName = map.get(obj.getField()).getColumnName();
                fieldList.add(columnName);

                if (obj.getOrderBy() != null) {
                    orderList.add(columnName + (obj.getOrderBy() ? " asc" : "desc"));
                }
            });
        }

        if (agrees != null) {
            agrees.forEach(obj -> {
                SqlAgreeEnum agreeEnum = obj.getAgreeEnum();
                if (agreeEnum == null) {
                    return;
                }
                if (agreeEnum == AGREE_COUNT || agreeEnum == AGREE_ID || agreeEnum == AGREE_ALL) {
                    fieldList.add(agreeEnum.getAgree() + agreeEnum.getAgree2());
                }
                else {
                    String columnName = map.get(obj.getField()).getColumnName();
                    fieldList.add(agreeEnum.getAgree() + columnName + agreeEnum.getAgree2() + columnName);
                }
            });
        }
        if (groups != null) {
            groups.forEach(obj -> {
                String columnName = map.get(obj.getField()).getColumnName();
                groupList.add(columnName);
            });
        }

        if (searchs != null) {
            searchs.forEach(obj -> {
                SqlOperateEnum operate = obj.getOperate();
                Boolean operateType = obj.getOperateType();
                if (operate == null || operateType == null) {
                    return;
                }
                String columnName = map.get(obj.getField()).getColumnName();
                StringBuilder sb = new StringBuilder(operateType ? "and " : "or ");
                sb.append("(");
                sb.append(columnName);
                sb.append(" ");

                sb.append(operate.getOperate());
                Map<String, Object> seacrh = new HashMap<>();
                seacrh.put("prefix", sb.toString());
                if (operate == OPERATE_LIKE) {
                    seacrh.put("middle", "%" + obj.getKeyValue() + "%");
                }

                if (operate == OPERATE_LIKE_RIGHT) {
                    seacrh.put("middle", obj.getKeyValue() + "%");
                }
                if (operate == OPERATE_IN) {
                    seacrh.put("middleList", obj.getKeyValueList());

                }
                else {
                    seacrh.put("middle", obj.getKeyValue());
                }
                seacrh.put("suffix", ")");
                searchList.add(seacrh);
            });
        }

        //        DqGroupEnum dqGroupEnum = bo.getDqGroupEnum();
        //        RqGroupEnum rqGroupEnum = bo.getRqGroupEnum();

        Page<List<Map<String, Object>>> page = customMapper.customQuery(pageQuery.build(), table.getTableName(),
                CollectionUtil.join(fieldList, ","), searchList, CollectionUtil.join(groupList, ","),
            CollectionUtil.join(orderList, ","));


        return TableDataInfo.build(page);
    }
}
